/**
 * Copyright (c) Software Institude of PKU
 * All rights reserved. 
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 */
package edu.pku.sei.modeler.commands;

import org.eclipse.gef.commands.Command;

import edu.pku.sei.modeler.model.core.MetaClass;
import edu.pku.sei.modeler.model.core.MetaGeneralization;
import edu.pku.sei.modeler.model.core.MetaReference;
import edu.pku.sei.modeler.model.structure.MetaLink;
import edu.pku.sei.modeler.model.structure.MetaNode;

/**
 * @author zl
 *
 */
public class DeleteLinkCommand extends Command {
	private MetaLink link;
	private MetaNode src, target;
	private int srcIndex, targetIndex;
	private Command modelCmd;
	
	public DeleteLinkCommand(MetaLink link) {
		super("Delete Connection");
		this.link = link;
		src = link.getSource();
		target = link.getTarget();
		Object element = link.getModelElement();
		if(element instanceof MetaReference) {
			modelCmd = new DeleteAssoCommand((MetaReference)element);
		}
		else if(element instanceof MetaGeneralization) {
			modelCmd = new DeleteGenCommand((MetaGeneralization)element);
		}
	}
	public boolean canExecute() {
		return link != null && src != null && target != null;
	}
	public void execute() {
		srcIndex = src.getOutgoings().indexOf(link);
		targetIndex = target.getIncomings().indexOf(link);
		if (srcIndex != -1) {
			src.getOutgoings().remove(srcIndex);
			target.getIncomings().remove(targetIndex);
		}
		if(modelCmd != null) {
			modelCmd.execute();
		}
		
	}
	public void undo() {
		if (srcIndex != -1) {
			src.getOutgoings().add(srcIndex, link);
			target.getIncomings().add(targetIndex, link);
		}
	}
	
	private class DeleteAssoCommand extends Command
	{
		private MetaClass src, des;
		private MetaReference ref;
		
		public DeleteAssoCommand(MetaReference ref) {
			this.ref = (MetaReference)ref;
			this.src = (MetaClass)ref.getContainer();
		}
		
		public boolean canExecute() {
			return true;
		}
		
		public void execute() {
			if(src != null)
				src.getReferences().remove(ref);
			if(ref != null)
				ref.setContainer(null);
		}
		
		public void undo() {
			
		}
	}
	private class DeleteGenCommand extends Command
	{
		private MetaClass src, des;
		private MetaGeneralization gen;
		
		public DeleteGenCommand(MetaGeneralization gen) {
			this.gen = gen;
			this.src = (MetaClass)gen.getContainer();
		}
		
		public boolean canExecute() {
			return true;
		}
		
		public void execute() {
			if(src != null)
				src.getGenerals().remove(gen);
			if(gen != null)
				gen.setContainer(null);
		}
		
		public void undo() {
			
		}
	}
}
